package com.tinem.platform.web.file.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baidu.fsg.uid.UidGenerator;
import com.google.common.net.HttpHeaders;
import com.tinem.platform.module.pojo.co.GatewayHeadName;
import com.tinem.platform.module.pojo.vo.error.UserException;
import com.tinem.platform.module.starter.jpa.entity.config.ConfigWebFileClient;
import com.tinem.platform.module.starter.jpa.entity.file.FileUplaodRecord;
import com.tinem.platform.module.starter.jpa.repository.config.ConfigWebFileClientRepository;
import com.tinem.platform.module.starter.jpa.repository.file.FileUplaodRecordRepository;
import com.tinem.platform.module.starter.sdk.MessageCode;
import com.tinem.platform.module.starter.sdk.page.PlatformJwt;
import com.tinem.platform.module.starter.sdk.util.JwtUtil;
import com.tinem.platform.web.file.vo.UploadFileVO;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Optional;

/**
 * @author fengzhihao
 * @version v1
 * @program: platform
 * @className LinkController
 * @description TODO
 * @site 
 * @company 
 * @create 2020-07-13 19:53
 */
@Slf4j
@Controller
public class FileController {

    @Resource
    UidGenerator uidGenerator;

    @Resource
    ConfigWebFileClientRepository configWebFileClientRepository;

    @Resource
    FileUplaodRecordRepository fileUplaodRecordRepository;

    @Resource
    JwtUtil jwtUtil;
    @PostMapping("/uploadFile.api")
    @ResponseBody
    @ApiOperation(value = "文件保存到文件对应目录", httpMethod = "POST", notes = "暂无")
    @Transactional(rollbackOn = Exception.class)
    public Object uploadFile(@RequestParam("file") MultipartFile file,@RequestParam("fileName") String fileName,@RequestParam("jwt") String jwt) throws IOException {
        return saveFile(file.getSize(),jwt,file.getBytes(),fileName);
    }
    @PostMapping("/upload.api")
    @ResponseBody
    @ApiOperation(value = "文件保存到文件对应目录", httpMethod = "POST", notes = "暂无")
    @Transactional(rollbackOn = Exception.class)
    public Object upload(@Validated @RequestBody UploadFileVO req, HttpServletRequest request){

        String contentLengthHead = request.getHeader(HttpHeaders.CONTENT_LENGTH);
        if(StrUtil.isEmpty(contentLengthHead) || !NumberUtil.isNumber(contentLengthHead)){
            throw new UserException(MessageCode.ERROR_COMMONS_PARAMS,HttpHeaders.CONTENT_LENGTH);
        }
        String jwt = request.getHeader(GatewayHeadName.X_PLATFORM_GATEWAY_REQ_JWT);
        byte[] fileBody = Base64.decode(req.getFileBase64());
        return saveFile(Long.parseLong(contentLengthHead),jwt,fileBody,req.getFileName());
    }
    private FileUplaodRecord saveFile(Long fileSize,String jwt,byte[] fileBody,String fileName ){

        String channel = "";

        log.info("jwt:{}",jwt);
        try {
            if(StrUtil.isBlank(jwt)){
                return null;
            }
            PlatformJwt decodedJWT = jwtUtil.getDecodedJWT(jwt);
            channel = decodedJWT.getJwt().getClaim("client_id").asString();
        }catch (Exception e){
            log.error("e",e);
            throw new UserException(MessageCode.ERROR_PLATFORM_CLOUD_WEB_GATEWAY_SIGN_TYPE);
        }

        log.info("channel:{}",channel);

        Optional<ConfigWebFileClient> configWebFileClientOptional = configWebFileClientRepository.findById(channel);

        if(!configWebFileClientOptional.isPresent()){
            log.error("该客户端id对应的文件前缀没有配置");
            throw new UserException(MessageCode.ERROR_PLATFORM_CLOUD_WEB_GATEWAY_CLIENT_NOT_FIND);
        }
        ConfigWebFileClient configWebFileClient = configWebFileClientOptional.get();
        if(fileSize > configWebFileClient.getChennelFileMaxSize().longValue() ){
            throw new UserException(MessageCode.ERROR_PLATFORM_CLOUD_WEB_FILE_SIZE_LIMIT,HttpHeaders.CONTENT_LENGTH);
        }
        if(configWebFileClient.getChennelUseStorageSize().longValue()>configWebFileClient.getChennelStorageSize().longValue()){
            throw new UserException(MessageCode.ERROR_PLATFORM_CLOUD_WEB_STORAGE_SIZE_LIMIT,HttpHeaders.CONTENT_LENGTH);
        }
        String filePath = configWebFileClient.getChennelFilePrefix() + "/" + fileName;
        File file = FileUtil.writeBytes(fileBody,filePath);
        String type = FileTypeUtil.getType(file);
        FileUplaodRecord uplaodRecord = new FileUplaodRecord();
        uplaodRecord.setId(uidGenerator.getUID());
        uplaodRecord.setFileName(fileName);
        uplaodRecord.setFilePath(filePath);
        uplaodRecord.setJwt(jwt);
        uplaodRecord.setFileType(type);
        uplaodRecord.setFileSize(String.valueOf(fileBody.length));
        uplaodRecord.setFilePrefix(configWebFileClient.getChennelFilePrefix());
        uplaodRecord.setUploadChannel(channel);
        uplaodRecord.setCreatedTime(new Date());
        uplaodRecord.setUpdatedTime(new Date());
        uplaodRecord.setFileUrl(StrUtil.format(configWebFileClient.getChennelUrlPrefix(), BeanUtil.beanToMap(uplaodRecord)));
        fileUplaodRecordRepository.saveAndFlush(uplaodRecord);
        configWebFileClientRepository.updateUseStorage(channel,FileUtil.size(file));
        return uplaodRecord;
    }
}
